package com.ibm.risk.irmp.workflow.client.flowable.api;

import com.ibm.risk.irmp.workflow.client.flowable.ApiClient;

import java.io.File;
import com.ibm.risk.irmp.workflow.client.flowable.model.ProcessInstanceVariableCollectionResource;
import com.ibm.risk.irmp.workflow.client.flowable.model.ProcessInstanceVariableResource;
import com.ibm.risk.irmp.workflow.client.flowable.model.RestVariable;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;


@Component("com.ibm.risk.irmp.flowable.api.ProcessInstanceVariablesApi")
public class ProcessInstanceVariablesApi {
    private ApiClient apiClient;

    public ProcessInstanceVariablesApi() {
        this(new ApiClient());
    }

    @Autowired
    public ProcessInstanceVariablesApi(ApiClient apiClient) {
        this.apiClient = apiClient;
    }

    public ApiClient getApiClient() {
        return apiClient;
    }

    public void setApiClient(ApiClient apiClient) {
        this.apiClient = apiClient;
    }

    /**
     * Update a multiple/single (non)binary variable on a process instance
     * This endpoint can be used in 2 ways: By passing a JSON Body (RestVariable or an array of RestVariable) or by passing a multipart/form-data Object. Nonexistent variables are created on the process-instance and existing ones are overridden without any error. Any number of variables can be passed into the request body array. Note that scope is ignored, only local variables can be set in a process instance. NB: Swagger V2 specification does not support this use case that is why this endpoint might be buggy/incomplete if used with other tools.
     * <p><b>200</b> - successful operation
     * <p><b>201</b> - Indicates the process instance was found and variable is created.
     * <p><b>400</b> - Indicates the request body is incomplete or contains illegal values. The status description contains additional information about the error.
     * <p><b>404</b> - Indicates the requested process instance was not found.
     * <p><b>415</b> - Indicates the serializable data contains an object for which no class is present in the JVM running the Flowable engine and therefore cannot be deserialized.
     * @param processInstanceId The processInstanceId parameter
     * @param body Create a variable on a process instance
     * @param file The file parameter
     * @param name The name parameter
     * @param type The type parameter
     * @return Object
     * @throws RestClientException if an error occurs while attempting to invoke the API
     */
    public Object createOrUpdateProcessVariable(String processInstanceId, ProcessInstanceVariableCollectionResource body, File file, String name, String type) throws RestClientException {
        Object postBody = body;

        // verify the required parameter 'processInstanceId' is set
        if (processInstanceId == null) {
            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'processInstanceId' when calling createOrUpdateProcessVariable");
        }

        // create path and map variables
        final Map<String, Object> uriVariables = new HashMap<String, Object>();
        uriVariables.put("processInstanceId", processInstanceId);
        String path = UriComponentsBuilder.fromPath("/runtime/process-instances/{processInstanceId}/variables").buildAndExpand(uriVariables).toUriString();

        final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
        final HttpHeaders headerParams = new HttpHeaders();
        final MultiValueMap<String, Object> formParams = new LinkedMultiValueMap<String, Object>();

        if (file != null)
            formParams.add("file", new FileSystemResource(file));
        if (name != null)
            formParams.add("name", name);
        if (type != null)
            formParams.add("type", type);

        final String[] accepts = {
            "application/json"
        };
        final List<MediaType> accept = apiClient.selectHeaderAccept(accepts);
        final String[] contentTypes = {
            "application/json", "multipart/form-data"
        };
        final MediaType contentType = apiClient.selectHeaderContentType(contentTypes);

        String[] authNames = new String[] { "basicAuth" };

        ParameterizedTypeReference<Object> returnType = new ParameterizedTypeReference<Object>() {};
        return apiClient.invokeAPI(path, HttpMethod.PUT, queryParams, postBody, headerParams, formParams, accept, contentType, authNames, returnType);
    }
    /**
     * Create variables or new binary variable on a process instance
     * This endpoint can be used in 2 ways: By passing a JSON Body (RestVariable or an array of RestVariable) or by passing a multipart/form-data Object. Nonexistent variables are created on the process-instance and existing ones are overridden without any error. Any number of variables can be passed into the request body array. Note that scope is ignored, only local variables can be set in a process instance. NB: Swagger V2 specification does not support this use case that is why this endpoint might be buggy/incomplete if used with other tools.
     * <p><b>200</b> - successful operation
     * <p><b>201</b> - Indicates the process instance was found and variable is created.
     * <p><b>400</b> - Indicates the request body is incomplete or contains illegal values. The status description contains additional information about the error.
     * <p><b>404</b> - Indicates the requested process instance was not found.
     * <p><b>409</b> - Indicates the process instance was found but already contains a variable with the given name (only thrown when POST method is used). Use the update-method instead.
     * @param processInstanceId The processInstanceId parameter
     * @param body Create a variable on a process instance
     * @param file The file parameter
     * @param name The name parameter
     * @param type The type parameter
     * @return Object
     * @throws RestClientException if an error occurs while attempting to invoke the API
     */
    public Object createProcessInstanceVariable(String processInstanceId, ProcessInstanceVariableCollectionResource body, File file, String name, String type) throws RestClientException {
        Object postBody = body;

        // verify the required parameter 'processInstanceId' is set
        if (processInstanceId == null) {
            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'processInstanceId' when calling createProcessInstanceVariable");
        }

        // create path and map variables
        final Map<String, Object> uriVariables = new HashMap<String, Object>();
        uriVariables.put("processInstanceId", processInstanceId);
        String path = UriComponentsBuilder.fromPath("/runtime/process-instances/{processInstanceId}/variables").buildAndExpand(uriVariables).toUriString();

        final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
        final HttpHeaders headerParams = new HttpHeaders();
        final MultiValueMap<String, Object> formParams = new LinkedMultiValueMap<String, Object>();

        if (file != null)
            formParams.add("file", new FileSystemResource(file));
        if (name != null)
            formParams.add("name", name);
        if (type != null)
            formParams.add("type", type);

        final String[] accepts = {
            "application/json"
        };
        final List<MediaType> accept = apiClient.selectHeaderAccept(accepts);
        final String[] contentTypes = {
            "application/json", "multipart/form-data"
        };
        final MediaType contentType = apiClient.selectHeaderContentType(contentTypes);

        String[] authNames = new String[] { "basicAuth" };

        ParameterizedTypeReference<Object> returnType = new ParameterizedTypeReference<Object>() {};
        return apiClient.invokeAPI(path, HttpMethod.POST, queryParams, postBody, headerParams, formParams, accept, contentType, authNames, returnType);
    }
    /**
     * Delete all variables
     *
     * <p><b>204</b> - Indicates variables were found and have been deleted. Response-body is intentionally empty.
     * <p><b>404</b> - Indicates the requested process instance was not found.
     * @param processInstanceId The processInstanceId parameter
     * @throws RestClientException if an error occurs while attempting to invoke the API
     */
    public void deleteLocalProcessVariable(String processInstanceId) throws RestClientException {
        Object postBody = null;

        // verify the required parameter 'processInstanceId' is set
        if (processInstanceId == null) {
            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'processInstanceId' when calling deleteLocalProcessVariable");
        }

        // create path and map variables
        final Map<String, Object> uriVariables = new HashMap<String, Object>();
        uriVariables.put("processInstanceId", processInstanceId);
        String path = UriComponentsBuilder.fromPath("/runtime/process-instances/{processInstanceId}/variables").buildAndExpand(uriVariables).toUriString();

        final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
        final HttpHeaders headerParams = new HttpHeaders();
        final MultiValueMap<String, Object> formParams = new LinkedMultiValueMap<String, Object>();

        final String[] accepts = { };
        final List<MediaType> accept = apiClient.selectHeaderAccept(accepts);
        final String[] contentTypes = { };
        final MediaType contentType = apiClient.selectHeaderContentType(contentTypes);

        String[] authNames = new String[] { "basicAuth" };

        ParameterizedTypeReference<Void> returnType = new ParameterizedTypeReference<Void>() {};
        apiClient.invokeAPI(path, HttpMethod.DELETE, queryParams, postBody, headerParams, formParams, accept, contentType, authNames, returnType);
    }
    /**
     * Delete a variable
     *
     * <p><b>204</b> - Indicates the variable was found and has been deleted. Response-body is intentionally empty.
     * <p><b>404</b> - Indicates the requested variable was not found.
     * @param processInstanceId The processInstanceId parameter
     * @param variableName The variableName parameter
     * @param scope The scope parameter
     * @throws RestClientException if an error occurs while attempting to invoke the API
     */
    public void deleteProcessInstanceVariable(String processInstanceId, String variableName, String scope) throws RestClientException {
        Object postBody = null;

        // verify the required parameter 'processInstanceId' is set
        if (processInstanceId == null) {
            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'processInstanceId' when calling deleteProcessInstanceVariable");
        }

        // verify the required parameter 'variableName' is set
        if (variableName == null) {
            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'variableName' when calling deleteProcessInstanceVariable");
        }

        // create path and map variables
        final Map<String, Object> uriVariables = new HashMap<String, Object>();
        uriVariables.put("processInstanceId", processInstanceId);
        uriVariables.put("variableName", variableName);
        String path = UriComponentsBuilder.fromPath("/runtime/process-instances/{processInstanceId}/variables/{variableName}").buildAndExpand(uriVariables).toUriString();

        final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
        final HttpHeaders headerParams = new HttpHeaders();
        final MultiValueMap<String, Object> formParams = new LinkedMultiValueMap<String, Object>();

        queryParams.putAll(apiClient.parameterToMultiValueMap(null, "scope", scope));

        final String[] accepts = { };
        final List<MediaType> accept = apiClient.selectHeaderAccept(accepts);
        final String[] contentTypes = { };
        final MediaType contentType = apiClient.selectHeaderContentType(contentTypes);

        String[] authNames = new String[] { "basicAuth" };

        ParameterizedTypeReference<Void> returnType = new ParameterizedTypeReference<Void>() {};
        apiClient.invokeAPI(path, HttpMethod.DELETE, queryParams, postBody, headerParams, formParams, accept, contentType, authNames, returnType);
    }
    /**
     * Get a variable for a process instance
     *
     * <p><b>200</b> - Indicates both the process instance and variable were found and variable is returned.
     * <p><b>404</b> - Indicates the requested process instance was not found or the process instance does not have a variable with the given name. Status description contains additional information about the error.
     * @param processInstanceId The processInstanceId parameter
     * @param variableName The variableName parameter
     * @param scope The scope parameter
     * @return RestVariable
     * @throws RestClientException if an error occurs while attempting to invoke the API
     */
    public RestVariable getProcessInstanceVariable(String processInstanceId, String variableName, String scope) throws RestClientException {
        Object postBody = null;

        // verify the required parameter 'processInstanceId' is set
        if (processInstanceId == null) {
            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'processInstanceId' when calling getProcessInstanceVariable");
        }

        // verify the required parameter 'variableName' is set
        if (variableName == null) {
            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'variableName' when calling getProcessInstanceVariable");
        }

        // create path and map variables
        final Map<String, Object> uriVariables = new HashMap<String, Object>();
        uriVariables.put("processInstanceId", processInstanceId);
        uriVariables.put("variableName", variableName);
        String path = UriComponentsBuilder.fromPath("/runtime/process-instances/{processInstanceId}/variables/{variableName}").buildAndExpand(uriVariables).toUriString();

        final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
        final HttpHeaders headerParams = new HttpHeaders();
        final MultiValueMap<String, Object> formParams = new LinkedMultiValueMap<String, Object>();

        queryParams.putAll(apiClient.parameterToMultiValueMap(null, "scope", scope));

        final String[] accepts = {
            "application/json"
        };
        final List<MediaType> accept = apiClient.selectHeaderAccept(accepts);
        final String[] contentTypes = { };
        final MediaType contentType = apiClient.selectHeaderContentType(contentTypes);

        String[] authNames = new String[] { "basicAuth" };

        ParameterizedTypeReference<RestVariable> returnType = new ParameterizedTypeReference<RestVariable>() {};
        return apiClient.invokeAPI(path, HttpMethod.GET, queryParams, postBody, headerParams, formParams, accept, contentType, authNames, returnType);
    }
    /**
     * Get the binary data for a variable
     *
     * <p><b>200</b> - Indicates the process instance was found and the requested variables are returned.
     * <p><b>404</b> - Indicates the requested task was not found or the task does not have a variable with the given name (in the given scope). Status message provides additional information.
     * @param processInstanceId The processInstanceId parameter
     * @param variableName The variableName parameter
     * @param scope The scope parameter
     * @return List&lt;byte[]&gt;
     * @throws RestClientException if an error occurs while attempting to invoke the API
     */
    public List<byte[]> getProcessInstanceVariableData(String processInstanceId, String variableName, String scope) throws RestClientException {
        Object postBody = null;

        // verify the required parameter 'processInstanceId' is set
        if (processInstanceId == null) {
            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'processInstanceId' when calling getProcessInstanceVariableData");
        }

        // verify the required parameter 'variableName' is set
        if (variableName == null) {
            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'variableName' when calling getProcessInstanceVariableData");
        }

        // create path and map variables
        final Map<String, Object> uriVariables = new HashMap<String, Object>();
        uriVariables.put("processInstanceId", processInstanceId);
        uriVariables.put("variableName", variableName);
        String path = UriComponentsBuilder.fromPath("/runtime/process-instances/{processInstanceId}/variables/{variableName}/data").buildAndExpand(uriVariables).toUriString();

        final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
        final HttpHeaders headerParams = new HttpHeaders();
        final MultiValueMap<String, Object> formParams = new LinkedMultiValueMap<String, Object>();

        queryParams.putAll(apiClient.parameterToMultiValueMap(null, "scope", scope));

        final String[] accepts = { };
        final List<MediaType> accept = apiClient.selectHeaderAccept(accepts);
        final String[] contentTypes = { };
        final MediaType contentType = apiClient.selectHeaderContentType(contentTypes);

        String[] authNames = new String[] { "basicAuth" };

        ParameterizedTypeReference<List<byte[]>> returnType = new ParameterizedTypeReference<List<byte[]>>() {};
        return apiClient.invokeAPI(path, HttpMethod.GET, queryParams, postBody, headerParams, formParams, accept, contentType, authNames, returnType);
    }
    /**
     * List variables for a process instance
     * In case the variable is a binary variable or serializable, the valueUrl points to an URL to fetch the raw value. If it’s a plain variable, the value is present in the response. Note that only local scoped variables are returned, as there is no global scope for process-instance variables.
     * <p><b>200</b> - Indicates the process instance was found and variables are returned.
     * <p><b>400</b> - Indicates the requested process instance was not found.
     * @param processInstanceId The processInstanceId parameter
     * @param scope The scope parameter
     * @return List&lt;RestVariable&gt;
     * @throws RestClientException if an error occurs while attempting to invoke the API
     */
    public List<RestVariable> listProcessInstanceVariables(String processInstanceId, String scope) throws RestClientException {
        Object postBody = null;

        // verify the required parameter 'processInstanceId' is set
        if (processInstanceId == null) {
            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'processInstanceId' when calling listProcessInstanceVariables");
        }

        // create path and map variables
        final Map<String, Object> uriVariables = new HashMap<String, Object>();
        uriVariables.put("processInstanceId", processInstanceId);
        String path = UriComponentsBuilder.fromPath("/runtime/process-instances/{processInstanceId}/variables").buildAndExpand(uriVariables).toUriString();

        final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
        final HttpHeaders headerParams = new HttpHeaders();
        final MultiValueMap<String, Object> formParams = new LinkedMultiValueMap<String, Object>();

        queryParams.putAll(apiClient.parameterToMultiValueMap(null, "scope", scope));

        final String[] accepts = {
            "application/json"
        };
        final List<MediaType> accept = apiClient.selectHeaderAccept(accepts);
        final String[] contentTypes = { };
        final MediaType contentType = apiClient.selectHeaderContentType(contentTypes);

        String[] authNames = new String[] { "basicAuth" };

        ParameterizedTypeReference<List<RestVariable>> returnType = new ParameterizedTypeReference<List<RestVariable>>() {};
        return apiClient.invokeAPI(path, HttpMethod.GET, queryParams, postBody, headerParams, formParams, accept, contentType, authNames, returnType);
    }
    /**
     * Update a single variable on a process instance
     * This endpoint can be used in 2 ways: By passing a JSON Body (RestVariable) or by passing a multipart/form-data Object. Nonexistent variables are created on the process-instance and existing ones are overridden without any error. Note that scope is ignored, only local variables can be set in a process instance. NB: Swagger V2 specification does not support this use case that is why this endpoint might be buggy/incomplete if used with other tools.
     * <p><b>200</b> - successful operation
     * <p><b>201</b> - Indicates both the process instance and variable were found and variable is updated.
     * <p><b>404</b> - Indicates the requested process instance was not found or the process instance does not have a variable with the given name. Status description contains additional information about the error.
     * @param processInstanceId The processInstanceId parameter
     * @param variableName The variableName parameter
     * @param body Create a variable on a process instance
     * @param file The file parameter
     * @param name The name parameter
     * @param type The type parameter
     * @return RestVariable
     * @throws RestClientException if an error occurs while attempting to invoke the API
     */
    public RestVariable updateProcessInstanceVariable(String processInstanceId, String variableName, ProcessInstanceVariableResource body, File file, String name, String type) throws RestClientException {
        Object postBody = body;

        // verify the required parameter 'processInstanceId' is set
        if (processInstanceId == null) {
            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'processInstanceId' when calling updateProcessInstanceVariable");
        }

        // verify the required parameter 'variableName' is set
        if (variableName == null) {
            throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "Missing the required parameter 'variableName' when calling updateProcessInstanceVariable");
        }

        // create path and map variables
        final Map<String, Object> uriVariables = new HashMap<String, Object>();
        uriVariables.put("processInstanceId", processInstanceId);
        uriVariables.put("variableName", variableName);
        String path = UriComponentsBuilder.fromPath("/runtime/process-instances/{processInstanceId}/variables/{variableName}").buildAndExpand(uriVariables).toUriString();

        final MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<String, String>();
        final HttpHeaders headerParams = new HttpHeaders();
        final MultiValueMap<String, Object> formParams = new LinkedMultiValueMap<String, Object>();

        if (file != null)
            formParams.add("file", new FileSystemResource(file));
        if (name != null)
            formParams.add("name", name);
        if (type != null)
            formParams.add("type", type);

        final String[] accepts = {
            "application/json"
        };
        final List<MediaType> accept = apiClient.selectHeaderAccept(accepts);
        final String[] contentTypes = {
            "application/json", "multipart/form-data"
        };
        final MediaType contentType = apiClient.selectHeaderContentType(contentTypes);

        String[] authNames = new String[] { "basicAuth" };

        ParameterizedTypeReference<RestVariable> returnType = new ParameterizedTypeReference<RestVariable>() {};
        return apiClient.invokeAPI(path, HttpMethod.PUT, queryParams, postBody, headerParams, formParams, accept, contentType, authNames, returnType);
    }
}
